home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 May / may_2001.iso / intercd / root / Multimedia / ^DivX_Article / virtualdub / VirtualDub-source-1_4d / CMemoryBitInput.h < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-20  |  10.0 KB  |  521 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Copyright (C) 1998-2001 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #ifndef f_CMEMORYBITINPUT_H
  19. #define f_CMEMORYBITINPUT_H
  20.  
  21. #define FORCEINLINE __inline
  22.  
  23. #if 1
  24.  
  25. class CMemoryBitInput {
  26. public:
  27.     unsigned char *buf;
  28.     int bitcnt;
  29.     unsigned char *buf_start;
  30.     unsigned long bitheap;
  31.  
  32. public:
  33.     CMemoryBitInput();
  34.     CMemoryBitInput(char *buffer);
  35.     CMemoryBitInput(CMemoryBitInput& cmbi) {
  36.         buf = cmbi.buf;
  37.         buf_start = cmbi.buf_start;
  38.         bitcnt = cmbi.bitcnt;
  39.         bitheap = cmbi.bitheap;
  40.     }
  41.  
  42.     bool FORCEINLINE get_flag() {
  43.         bool rv = (signed long)bitheap < 0;
  44.  
  45.         bitheap <<= 1;
  46.         if (++bitcnt==0) {
  47.             bitheap += (unsigned long)*buf++;
  48.             bitcnt = -8;
  49.         }
  50.  
  51.         return rv;
  52.     }
  53.  
  54.     long FORCEINLINE get() {
  55.         long rv = bitheap>>31;
  56.  
  57.         bitheap <<= 1;
  58.  
  59.         if (++bitcnt==0) {
  60.             bitheap += (unsigned long)*buf++;
  61.             bitcnt = -8;
  62.         }
  63.  
  64.         return rv;
  65.     }
  66.     long FORCEINLINE get(unsigned char bits) {
  67.         long rv = bitheap >> (32-bits);
  68.  
  69.         bitcnt += bits;
  70.  
  71.         bitheap <<= bits;
  72.  
  73.         refill();
  74.  
  75.         return rv;
  76.     }
  77.     long FORCEINLINE get8(unsigned char bits) {
  78.         long rv = bitheap >> (32-bits);
  79.  
  80.         bitcnt += bits;
  81.  
  82.         bitheap <<= bits;
  83.  
  84.         refill8();
  85.  
  86.         return rv;
  87.     }
  88.     long FORCEINLINE get2(unsigned char bits) {
  89.         long rv = bitheap >> (32-bits);
  90.  
  91.         bitcnt += bits;
  92.         bitheap <<= bits;
  93.  
  94.         return rv;
  95.     }
  96.     long __forceinline getconst(const unsigned char bits) {
  97.         long rv = bitheap >> (32-bits);
  98.  
  99.         bitcnt += bits;
  100.         bitheap <<= bits;
  101.  
  102.         if (bits >= 8) {
  103.             bitheap += ((unsigned long)*buf++) << bitcnt;
  104.             bitcnt -= 8;
  105.         }
  106.         if (bits >= 16) {
  107.             bitheap += ((unsigned long)*buf++) << bitcnt;
  108.             bitcnt -= 8;
  109.         }
  110.  
  111.         if (bits & 7)
  112.             refill8();
  113.  
  114.         return rv;
  115.     }
  116.     long FORCEINLINE get_signed(unsigned char bits) {
  117.         long rv = ((signed long)bitheap) >> (32-bits);
  118.  
  119.         bitcnt += bits;
  120.         bitheap <<= bits;
  121.  
  122.         refill();
  123.  
  124.         return rv;
  125.     }
  126.     long FORCEINLINE get_signed2(unsigned char bits) {
  127.         long rv = ((signed long)bitheap) >> (32-bits);
  128.  
  129.         bitcnt += bits;
  130.         bitheap <<= bits;
  131.  
  132.         return rv;
  133.     }
  134.     long FORCEINLINE get_signed_const(unsigned char bits) {
  135.         long rv = (signed long)bitheap >> (32-bits);
  136.  
  137.         bitcnt += bits;
  138.         bitheap <<= bits;
  139.  
  140.         if (bits >= 8) {
  141.             bitheap += ((unsigned long)*buf++) << bitcnt;
  142.             bitcnt -= 8;
  143.         }
  144.         if (bits >= 16) {
  145.             bitheap += ((unsigned long)*buf++) << bitcnt;
  146.             bitcnt -= 8;
  147.         }
  148.         if (bits >= 24) {
  149.             bitheap += ((unsigned long)*buf++) << bitcnt;
  150.             bitcnt -= 8;
  151.         }
  152.  
  153.         if (bits & 7)
  154.             refill8();
  155.  
  156.         return rv;
  157.     }
  158.  
  159.     unsigned long FORCEINLINE peek() const {
  160.         return bitheap;
  161.     }
  162.  
  163.     long FORCEINLINE peek(unsigned char bits) const {
  164.         return bitheap >> (32-bits);
  165.     }
  166.     long FORCEINLINE peek8(unsigned char bits) const {
  167.         return bitheap >> (32-bits);
  168.     }
  169.     void FORCEINLINE refill() {
  170.         while(bitcnt >= 0) {
  171.             bitheap += ((unsigned long)*buf++) << bitcnt;
  172.             bitcnt -= 8;
  173.         }
  174.     }
  175.     void FORCEINLINE refill8() {
  176.         if(bitcnt >= 0) {
  177.             bitheap += ((unsigned long)*buf++) << bitcnt;
  178.             bitcnt -= 8;
  179.         }
  180.     }
  181.  
  182.     long FORCEINLINE next() const {
  183.         return bitheap >> 31;
  184.     }
  185.  
  186.     bool FORCEINLINE next(unsigned char bits, long compare) const {
  187.         return (long)(bitheap >> (32-bits)) == compare;
  188.     }
  189.  
  190.     void FORCEINLINE skip() {
  191.         bitheap <<= 1;
  192.         if (++bitcnt==0) {
  193.             bitheap += (unsigned long)*buf++;
  194.             bitcnt = -8;
  195.         }
  196.     }
  197.     void FORCEINLINE skip(unsigned char bits) {
  198.         bitcnt += bits;
  199.         bitheap <<= bits;
  200.  
  201.         refill();
  202.     }
  203.     void FORCEINLINE skip8(unsigned char bits) {
  204.         bitcnt += bits;
  205.         bitheap <<= bits;
  206.  
  207.         refill8();
  208.     }
  209.     void FORCEINLINE skip2(unsigned char bits) {
  210.         bitcnt += bits;
  211.         bitheap <<= bits;
  212.     }
  213.     void __forceinline skipconst(const unsigned char bits) {
  214.         bitcnt += bits;
  215.         bitheap <<= bits;
  216.  
  217.         if (bits >= 8) {
  218.             bitheap += ((unsigned long)*buf++) << bitcnt;
  219.             bitcnt -= 8;
  220.         }
  221.         if (bits >= 16) {
  222.             bitheap += ((unsigned long)*buf++) << bitcnt;
  223.             bitcnt -= 8;
  224.         }
  225.  
  226.         if (bits & 7)
  227.             refill8();
  228.     }
  229.  
  230.     void bytealign() {
  231.         while(bitcnt&7) {
  232.             bitheap <<= 1;
  233.             bitcnt ++;
  234.         }
  235.         while(bitcnt >= 0) {
  236.             bitheap += ((unsigned long)*buf++) << bitcnt;
  237.             bitcnt -= 8;
  238.         }
  239.     }
  240.  
  241.     long bytecount() {
  242.         return buf - buf_start - (24-bitcnt)/8;
  243.     }
  244. };
  245.  
  246. #elif 1
  247.  
  248. class CMemoryBitInput {
  249. private:
  250.     unsigned char *buf;
  251.     int bitcnt;
  252.     unsigned char *buf_start;
  253.     unsigned long bitheap;
  254.  
  255. public:
  256.     CMemoryBitInput();
  257.     CMemoryBitInput(char *buffer);
  258.     CMemoryBitInput(CMemoryBitInput& cmbi) {
  259.         buf = cmbi.buf;
  260.         buf_start = cmbi.buf_start;
  261.         bitcnt = cmbi.bitcnt;
  262.         bitheap = cmbi.bitheap;
  263.     }
  264.  
  265.     long FORCEINLINE get_flag() {
  266.         if (bitcnt == 24)
  267.             while(bitcnt >= 0) {
  268.                 bitheap += ((unsigned long)*buf++) << bitcnt;
  269.                 bitcnt -= 8;
  270.             }
  271.  
  272.         const unsigned long rv = bitheap;
  273.  
  274.         bitheap <<= 1;
  275.         ++bitcnt;
  276.  
  277.         return (signed long)rv;
  278.     }
  279.  
  280.     char FORCEINLINE get() {
  281.         char rv;
  282.         
  283.         if (bitcnt == 24)
  284.             while(bitcnt >= 0) {
  285.                 bitheap += ((unsigned long)*buf++) << bitcnt;
  286.                 bitcnt -= 8;
  287.             }
  288.  
  289.         rv = bitheap>>31;
  290.  
  291.         bitheap <<= 1;
  292.  
  293.         ++bitcnt;
  294.  
  295.         return rv;
  296.     }
  297.     long FORCEINLINE get(unsigned char bits) {
  298.         long rv;
  299.  
  300.         if (bitcnt >= 24-(int)bits)
  301.             while(bitcnt >= 0) {
  302.                 bitheap += ((unsigned long)*buf++) << bitcnt;
  303.                 bitcnt -= 8;
  304.             }
  305.         
  306.         rv = bitheap >> (32-bits);
  307.  
  308.         bitcnt += bits;
  309.  
  310.         bitheap <<= bits;
  311.  
  312.         return rv;
  313.     }
  314.     long FORCEINLINE get_signed(unsigned char bits) {
  315.         long rv;
  316.  
  317.         if (bitcnt >= 24-(int)bits)
  318.             while(bitcnt >= 0) {
  319.                 bitheap += ((unsigned long)*buf++) << bitcnt;
  320.                 bitcnt -= 8;
  321.             }
  322.         
  323.         rv = (signed long)bitheap >> (32-bits);
  324.  
  325.         bitcnt += bits;
  326.  
  327.         bitheap <<= bits;
  328.  
  329.         return rv;
  330.     }
  331.     long FORCEINLINE peek(unsigned char bits) {
  332.         long rv;
  333.  
  334.         if (bitcnt >= 24-(int)bits)
  335.             while(bitcnt >= 0) {
  336.                 bitheap += ((unsigned long)*buf++) << bitcnt;
  337.                 bitcnt -= 8;
  338.             }
  339.         
  340.         return bitheap >> (32-bits);
  341.     }
  342.     long FORCEINLINE peek8(unsigned char bits) {
  343.         long rv;
  344.  
  345.         if (bitcnt >= 24-(int)bits)
  346.             while(bitcnt >= 0) {
  347.                 bitheap += ((unsigned long)*buf++) << bitcnt;
  348.                 bitcnt -= 8;
  349.             }
  350.         
  351.         return bitheap >> (32-bits);
  352.     }
  353.  
  354.     long FORCEINLINE next() {
  355.         long rv;
  356.  
  357.         if (bitcnt == 24)
  358.             while(bitcnt >= 0) {
  359.                 bitheap += ((unsigned long)*buf++) << bitcnt;
  360.                 bitcnt -= 8;
  361.             }
  362.         
  363.         return bitheap >> 31;
  364.     }
  365.  
  366.     bool FORCEINLINE next(unsigned char bits, long compare) {
  367.         long rv;
  368.  
  369.         if (bitcnt >= 24-(int)bits)
  370.             while(bitcnt >= 0) {
  371.                 bitheap += ((unsigned long)*buf++) << bitcnt;
  372.                 bitcnt -= 8;
  373.             }
  374.         
  375.         return (long)(bitheap >> (32-bits)) == compare;
  376.     }
  377.  
  378.     void FORCEINLINE skip(unsigned char bits) {
  379.         bitcnt += bits;
  380.         bitheap <<= bits;
  381.  
  382.     }
  383.  
  384.     void bytealign() {
  385.         while(bitcnt&7) {
  386.             bitheap <<= 1;
  387.             bitcnt ++;
  388.         }
  389.         while(bitcnt >= 0) {
  390.             bitheap += ((unsigned long)*buf++) << bitcnt;
  391.             bitcnt -= 8;
  392.         }
  393.     }
  394.  
  395.     long bytecount() {
  396.         return buf - buf_start - (24-bitcnt)/8;
  397.     }
  398. };
  399.  
  400. #else
  401.  
  402. class CMemoryBitInput {
  403. private:
  404.     unsigned char *buf;
  405.     int bitcnt;
  406.     unsigned char *buf_start;
  407.  
  408. public:
  409.     CMemoryBitInput();
  410.     CMemoryBitInput(char *buffer);
  411.     CMemoryBitInput(CMemoryBitInput& cmbi) {
  412.         buf = cmbi.buf;
  413.         buf_start = cmbi.buf_start;
  414.         bitcnt = cmbi.bitcnt;
  415.     }
  416.  
  417.     char get_flag() {
  418.         char rv = buf[0] & (0x80 >> bitcnt);
  419.  
  420.         if (++bitcnt > 7) {
  421.             bitcnt = 0;
  422.             ++buf;
  423.         }
  424.  
  425.         return rv;
  426.     }
  427.  
  428.     char get() {
  429.         char rv = (buf[0]>>(7-bitcnt)) & 1;
  430.  
  431.         if (++bitcnt > 7) {
  432.             bitcnt = 0;
  433.             ++buf;
  434.         }
  435.  
  436.         return rv;
  437.     }
  438.     long get(unsigned char bits) {
  439.         unsigned long rv;
  440.         unsigned char *buf2 = buf;
  441.  
  442.         _asm {
  443.             mov eax,[buf2]
  444.             mov eax,[eax]
  445.             bswap eax
  446.             mov rv,eax
  447.  
  448.         }
  449. //        rv = (unsigned long)(((unsigned long)buf[0] << 24) | ((unsigned long)buf[1] << 16) | ((unsigned long)buf[2] << 8) | (unsigned long)buf[3]);
  450. //        if (bitcnt) rv = (rv<<bitcnt) | (buf[4]>>(8-bitcnt));
  451.         rv = (rv<<bitcnt) | ((unsigned long)buf[4]>>(8-bitcnt));
  452.  
  453.         rv >>= (32-bits);
  454.  
  455.         bitcnt += bits;
  456.         buf += bitcnt>>3;
  457.         bitcnt &= 7;
  458.  
  459.         return rv;
  460.     }
  461.     long peek(unsigned char bits) const {
  462.         unsigned long rv;
  463.         unsigned char *buf2 = buf;
  464.  
  465.         _asm {
  466.             mov eax,buf2
  467.             mov eax,[eax]
  468.             bswap eax
  469.             mov rv,eax
  470.         }
  471.  
  472.         //rv = (unsigned long)(((unsigned long)buf[0] << 24) | ((unsigned long)buf[1] << 16) | ((unsigned long)buf[2] << 8) | (unsigned long)buf[3]);
  473. //        if (bitcnt) rv = (rv<<bitcnt) | (buf[4]>>(8-bitcnt));
  474. //        rv<<=bitcnt;
  475.  
  476.         return (rv >> ((32-bits)-bitcnt)) & ((1L<<bits)-1);
  477.     }
  478.     long peek8(unsigned char bits) const {
  479.         unsigned long rv;
  480.  
  481.         rv = (unsigned long)(((unsigned long)buf[0] << 8) | (unsigned long)buf[1]);
  482.  
  483.         return (rv >> ((16-bits)-bitcnt)) & ((1L<<bits)-1);
  484.     }
  485.  
  486.     long next() const {
  487.         return (buf[0]>>(7-(bitcnt&7))) & 1;
  488.     }
  489.  
  490.     long next(unsigned char bits, long compare) const {
  491.         unsigned long rv;
  492.         unsigned char *buf2 = buf;
  493.  
  494.         _asm {
  495.             mov eax,buf2
  496.             mov eax,[eax]
  497.             bswap eax
  498.             mov rv,eax
  499.         }
  500.  
  501. //        rv = (unsigned long)(((unsigned long)buf[0] << 24) | ((unsigned long)buf[1] << 16) | ((unsigned long)buf[2] << 8) | (unsigned long)buf[3]);
  502.         if (bitcnt) rv = (rv<<bitcnt) | (buf[4]>>(8-bitcnt));
  503.  
  504.         return (long)(rv >> (32-bits)) == compare;
  505.     }
  506.     void skip(unsigned char bits) {
  507.         bitcnt += bits;
  508.         buf += bitcnt>>3;
  509.         bitcnt &= 7;
  510.     }
  511.     long bytecount() {
  512.         return buf - buf_start;
  513.     }
  514. };
  515.  
  516. #endif
  517.  
  518. #undef INLINE
  519.  
  520. #endif
  521.